#include "ws_connection.h"
#include "utils_log.h"
#include "common_property.h"

namespace El {
namespace Restful {

WebSocketConnection::WebSocketConnection(int64_t connection_id) : connection_id_(connection_id)
{
    protocol_ = Protocol::IProtocol::GetCustomInstance("websocket");
}

bool WebSocketConnection::IsAuthRequired(const std::string &method) const
{
    if (Common::CommonProperty::GetInstance().GetProperty("protocol.auth", "on") == "off") {
        EL_INFO("Auth is off");
        return false;
    }
    return non_auth_methods_.find(method) == non_auth_methods_.end();
}

bool WebSocketConnection::IsAuthenticated() const
{
    return is_authenticated_;
}

void WebSocketConnection::SetAuthenticated(bool authenticated, const std::string &user_id)
{
    is_authenticated_ = authenticated;
    authenticated_user_id_ = user_id;
    EL_DEBUG("Connection {} authentication status changed to {}, user_id: {}", connection_id_, authenticated, user_id);
}

std::string WebSocketConnection::ProcessEvent(std::shared_ptr<El::WebServer::WebSocketEvent> &event)
{
    // EL_DEBUG("Processing WebSocket event on connection {}: {}", connection_id_, event->message);

    try {
        std::string id;
        std::string method;
        nlohmann::json params;

        // 使用 ProtocolImpl 解析请求
        if (!protocol_->ParseRequest(event->message, id, method, params)) {
            EL_ERROR("Failed to parse WebSocket request on connection {}: {}", connection_id_, event->message);
            return protocol_->CreateErrorResponse("", -32700, "Parse error");
        }

        EL_DEBUG("Parsed request - connection: {}, id: {}, method: {}", connection_id_, id, method);

        // 检查是否需要鉴权
        if (IsAuthRequired(method) && !IsAuthenticated()) {
            EL_ERROR("Unauthorized access attempt on connection {} for method: {}", connection_id_, method);
            return protocol_->CreateErrorResponse(id, -32001, "Unauthorized access");
        }

        // 使用 ProtocolImpl 处理消息
        nlohmann::json response;
        if (!protocol_->HandleMessage(id, method, params, response)) {
            return response.dump();
        }

        // 处理认证状态变更
        if (method == "auth.login" && !response.contains("error")) {
            auto result = response["result"];
            if (result.contains("user") && result["user"].contains("id")) {
                SetAuthenticated(true, result["user"]["id"]);
            }
        } else if (method == "auth.logout" && !response.contains("error")) {
            SetAuthenticated(false, "");
        }

        return response.dump();

    } catch (const std::exception &e) {
        EL_ERROR("Exception in ProcessEvent on connection {}: {}", connection_id_, e.what());
        return protocol_->CreateErrorResponse("", -32603, "Internal error");
    }
}

} // namespace Restful
} // namespace El